<?php
/**
 * Created by PhpStorm.
 * User: jyolo
 * Date: 2017/3/17
 * Time: 16:17
 */

namespace app\base\library;
use app\base\model\Models;
use app\base\model\ModelsFields;
use think\Db;

class ReverseModel
{

    static $error = false;


    /**
     * 获取所有的数据表及表注释
     */
    public static function get_tables(){
        $sql = 'show table status';
        $res = Db::query($sql);
        foreach($res as $k => $v){
            //剔除掉没有注释的表
            if(empty($v['Comment']))continue;
            $tables[$k]['Name'] = $v['Name'];
            $tables[$k]['Comment'] = $v['Comment'];
        }
        return $tables;
    }

    /**
     * @param string table name
     */
    public static function init($table = ''){
        if(!$table)self::$error = '缺少tables参数';

        $field = self::get_field_info($table);
        $table = self::get_table_info($table);

        Db::startTrans();
        $table_data = self::data_format($table ,'table');
        $models = Models::create($table_data);
        
        if(!$models->id){
            self::$error = '写入models 失败';
            Db::rollback();
            return false;
        }

        $field_data = self::data_format($field ,'field' ,$models->id);
        $models_field = new ModelsFields();
        $flag = $models_field->saveAll($field_data);
        if(!$flag){
            self::$error = '写入models_field 失败';
            Db::rollback();
            return false;
        }

        Db::commit();

        return true;

    }

    /**
     * 获取表的字段信息
     * @param $table
     * @return mixed
     */
    protected static function get_field_info($table){
        $sql = 'show full fields from '.$table;
        $field = Db::query($sql);
        return $field;
    }

    /**
     * 获取表信息 和 注释
     * example：审核；type(radio[未审核|0,已审核|1]) validate([require|max:20,必填|最大长度20,add&edit]) relation([38,id,code])
     * 如果字段名称中文后面有 type validate 或者 relation 需要在后面加上 ；分割
     */
    protected static function get_table_info($table){
        $sql = 'show table status where Name = "'.$table.'"';
        $table_info = Db::query($sql);
        return $table_info;
    }

    /**
     * 数据映射格式化
     */
    protected static function data_format($data ,$type ,$models_id = false){
        $return = [];
        switch ($type){
            case 'field':

                foreach($data as $k => $v){

                    $comment = self::get_comment($v);
                    if($models_id) $return[$k]['models_id'] = $models_id;
                    $return[$k]['name_zh'] = is_array($comment) ? $comment[0]:$comment;
                    $return[$k]['name_en'] = $v['Field'];
                    $return[$k]['comment'] = $v['Comment'];
                    $type = self::get_field_type($v['Type']);

                    $return[$k]['type'] = $type['type'];
                    $return[$k]['length'] = $type['length'];

                    
                    if(is_array($comment)){
                        $form_option = self::get_form_option($v);
                        $return[$k]['form_type'] = $form_option['type'];
                        $return[$k]['form_option'] = $form_option['form_option'];

                        $return[$k]['validate'] = self::get_validate($v);
                        $return[$k]['relation'] = self::get_relation($v);

                    }




                }

                break;
            case 'table':
                $return['models_name'] = $data[0]['Comment'];
                $return['table_name'] = str_replace(C('database.prefix'),'',$data[0]['Name']);
                $return['manager_id'] = session('manager.id');
                $return['manager_name'] = session('manager.login_name');
                break;
        }


        return $return;
    }

    protected static function get_comment($data){
            $split = '；';
            if(strpos($data['Comment'],$split)){
                $commet = explode($split,$data['Comment']);
            }else{
                $commet = $data['Comment'];
            }

        return $commet;
    }

    protected static function get_validate($data){
        preg_match('/validate\((.*?)\[(.*?)\]\)/',$data['Comment'],$match);
        if(count($match)){
            $find = ['[',']'];
            $str = str_replace($find,'',$match[2]);
            $arr = explode(',',$str);


            $return['rule'] = isset($arr[0]) ? json_encode($arr[1]) : '';
            $return['massage'] = isset($arr[1]) ? json_encode($arr[1]) : '';
            $return['scene'] = isset($arr[2]) ? str_replace('&',',',$arr[2]):'';
            return json_encode($return);
        }else{
            return '';
        }


    }

    protected static function get_relation($data){
        preg_match('/relation\((.*?)\[(.*?)\]\)/',$data['Comment'],$match);
        if($match){
            $find = ['[',']'];
            $str = str_replace($find,'',$match[2]);
            $arr = explode(',',$str);

            $return['models_id'] = $arr[0];
            $return['relation_field'] = $arr[1];
            $return['show_field'] = $arr[2];
            return json_encode($return);
        }else{
            return '';
        }

    }

    protected static function get_field_type($type){
        $type = explode('(',$type);
        $return['type'] = $type[0];
        if(isset($type[1])){
            preg_match('/\d+/',$type[1],$match);
        }
        $return['length'] = isset($match[0]) ? $match[0]:'0';
        return $return;
    }

    protected static function get_form_option($data){

        preg_match('/type\((.*?)(\[(.*?)\])?\)/',$data['Comment'],$match);


        $return['type'] = $match[1];
        if(isset($match[3])){

            $return['form_option'] = json_encode(explode(',',$match[3]));
            
        }else{
            $return['form_option'] = '';
        }


        return $return;
    }

}